<template>
  <div class="v-enter-from v-enter-active">
    <div class="el-input el-input-group el-input-group--append">
      <div class="el-input__wrapper">
        <input class="el-input__inner" type="text" style="height: 32px;cursor: pointer;"
               autocomplete="off" tabindex="0"
               :readonly="readonly" v-model="valueModel"
               :placeholder="props.placeholder" @click="clickPanel"/>
        <span style="align-items: center;color: lightgray;"
              v-if="clearable" v-show="hasText">
          <i class="fa fa-fw fa-times-circle-o" style="cursor: pointer" @click="clean"></i>
        </span>
      </div>
      <div class="el-input-group__append">
        <button aria-disabled="false" type="button" class="el-button" @click="clickButton">
          <span class=""><i class="fa fa-fw fa-search"></i></span></button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {computed} from "vue";
import Layers from "@/lang/layers";

/**
 * 基础搜索面板
 *
 * 这是一个基础组件，本身就是加了搜索按钮的输入框。
 *
 * 一般用法：点击之后，触发弹出层，在弹出层中进行选择，之后回显到输入框中
 *
 * 会有两种情况：
 * - 输入框仅用于数据展示，整个组件都允许点击；
 * - 输入框允许编辑，则只有按钮部分可点；
 *
 * 几种常见的设计：
 * - 点击后，下拉一个面板，从面板中获取值；
 * - 很多个按钮，公用一个面板，点击的时候，面板吸附到对应的按钮。
 */
interface Props {
    /** model-value */
    modelValue: number | string
    /** 组件大小 */
    size?: string
    /** 输入框的占位文字提示 */
    placeholder?: string

    /** 是否只读，除了禁用输入框，还会允许点击触发弹窗 */
    readonly?: boolean
    /** 是否显示清除按钮 */
    clearable?: boolean
}

// 使用 withDefaults 设置默认值
const props = withDefaults(defineProps<Props>(), {
    size: 'default',
    placeholder: '',
    clearable: true,
    readonly: false
})

// Emits
const emit = defineEmits(['update:modelValue', 'click', 'change']);

// 定义要触发的事件，用于更新 v-model 的值
const hasText = computed(() => {
    return Layers.isNotEmpty(props.modelValue);
});

/**
 * 面板点击事件
 *
 * @param e
 */
const clickPanel = (e: Event) => {
    if (props.readonly) {
        emit('click', e);
    }
}

/**
 * 按钮点击事件
 *
 * @param e - 点击事件
 */
const clickButton = (e: Event) => {
    emit('click', e);
}

// 定义要触发的事件，用于更新 v-model 的值
const valueModel = computed({
    get() {
        return props.modelValue;
    },
    set(val) {
        emit('update:modelValue', val);
        emit('change', val);
    }
});

// 文本变化事件
const clean = (e) => {
    const val = '';
    emit('update:modelValue', val);
    emit('change', val);
}

</script>
